/*
 * CurvaSpline.cpp
 *
 *  Created on: 15/10/2013
 *      Author: ezequiel
 */

#include "CurvaSpline.h"

//PRE: minimo 4 puntos en el buffer de puntos de control, divisiones > 1
CurvaSpline::CurvaSpline(vector<glm::vec3> pControl, int divisiones) {
	this->divisiones = divisiones;	//de aca saco delta u
	this->pControl = pControl;	//me guardo una copia de los puntos de control
	u = 0;

	/// seteo los primeros cuatro puntos ////
//	for(int i = 0 ; i < 4; i++)
//	this->grupoDe4.push_back(pControl[i]);

	p0 = pControl[0];
	p1 = pControl[1];
	p2 = pControl[2];
	p3 = pControl[3];
	iterador = 4;	//feo , pero lo dejo por ahora
//	cout << p0.x << " " << p1.x << " " << p2.x << " " << p3.x << endl;
	terminado = false;
}

CurvaSpline::~CurvaSpline() {
	// TODO Auto-generated destructor stub
}


/// calculo de los polinomios de spline ///

float CurvaSpline::getB0(float a) {
	return (1 - 3 * a + 3 * a * a - a * a * a) / 6.0f;
}

float CurvaSpline::getB1(float a) {
	return (4 - 6 * a * a + 3 * a * a * a)/6.0f;
}

float CurvaSpline::getB2(float a) {
	return (1 + 3 * a + 3 * a * a - 3 * a * a * a)/6.0f;
}


float CurvaSpline::getB3(float a) {
	return (a * a * a)/6.0f;
}

/// funcion que devuelve el set de puntos ///
vector<glm::vec3> CurvaSpline::obtenerPuntos() {
	vector<glm::vec3> vectorReturn;
	while(!this->terminado)
	{
		vectorReturn.push_back(this->proximoPunto());
	}
	return vectorReturn;
}

/// funcion qe devuelve el proximo punto del buffer retorno
glm::vec3 CurvaSpline::proximoPunto()
{

glm::vec3 puntoRetorno = p0 * getB0(u) + p1 * getB1(u) + p2 * getB2(u) + p3 * getB3(u);
u = u +  1/this->divisiones;

//TODO ver cuando se modifican los 4 puntos (osea cdo u = 1)
if (u > 1)
{
//	u = 1 ;
	glm::vec3 nuevoPunto = this->pControl[iterador];
	iterador++;
	if(iterador < this->pControl.size() + 1)
	{
		p0 = p1;
		p1 = p2;
		p2 = p3;
		p3 = nuevoPunto;
		u= 0;
	}
	else
	{	/// llegue al punto final y no queda mas nada en el buffer de puntos de control
		terminado = true;
	}
}
//cout << terminado << endl;
//cout << puntoRetorno.x << " " <<  puntoRetorno.y << " " <<  puntoRetorno.z << " " << u << endl;
return puntoRetorno;
}
